package com.alibaba.dubbo.dynamic.service.impl;

import com.alibaba.dubbo.dynamic.dao.BaseDao;
import com.alibaba.dubbo.dynamic.service.BaseRest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;

/**
 * @param <T> 实体
 * @param <Q> 查询条件
 * @param <P> 主键
 * @author wuyu
 */
public abstract class BaseRestImpl<T, Q, P> implements BaseRest<T, Q, P> {

    /**
     * 处理持久化操作的基类n
     */
    protected BaseDao<T, Q> baseDao;

    public abstract void setDao();

    // 用于json转对象
    private Class<?> type = null;

    private Class<?> example = null;

    // 用于获取插入数据表中返回的主键方法
    // private Method getPk = null;

    public BaseRestImpl() {
        // 获取泛型参数,防止CGLIB两次加载
        if (type == null && !this.getClass().getName().contains("EnhancerBySpringCGLIB")) {
            if (this.getClass().getGenericSuperclass() instanceof ParameterizedType) {
                ParameterizedType superGclass = (ParameterizedType) this.getClass().getGenericSuperclass();
                Type[] arguments = superGclass.getActualTypeArguments();

                if (arguments.length > 0) {
                    type = (Class<?>) arguments[0];
                    example = (Class<?>) arguments[1];
                }
            }
            // Class<?> superclazz = type.getSuperclass();
            // getPk = superclazz.getMethod("getPk");
        }
    }

    @Transactional(readOnly = true)
    public List<T> list(Integer startNum, Integer limit) {
        setDao();
        return baseDao.selectWithPage(Arrays.asList(startNum, limit));
    }

    public List<T> selectByRequestBodyIds(@RequestBody List<P> ids) {
        return selectByPrimaryKeys(ids);
    }

    // 根据条件查询 相应结果
    @Transactional(readOnly = true)
    public T selectByPrimaryKey(@PathVariable("id") P id) {
        setDao();
        return baseDao.selectByPrimaryKey(id);
    }

    @Transactional(readOnly = true)
    public List<T> selectByPrimaryKeys(@RequestBody List<P> ids) {
        setDao();
        if (ids != null && ids.size() == 1) {
            return Arrays.asList(baseDao.selectByPrimaryKey(ids.get(0)));
        }
        return baseDao.selectByPrimaryKeys(ids);
    }

    // 根据条件查询 相应结果
    @Transactional(readOnly = true)
    public List<T> selectByExample(@RequestBody Q example) {
        setDao();
        return baseDao.selectByExample(example);
    }


    /**
     * 新增业务
     */
    @Transactional
    public Object insert(@RequestBody T t) {
        setDao();
        setPrimaryKey(t);
        return baseDao.insert(t);
    }

    @Transactional
    public Object insertSelective(@RequestBody T t) {
        setDao();
        setPrimaryKey(t);
        return baseDao.insertSelective(t);
    }

    /**
     * for循环插入效率不高
     */
    @Transactional
    public Object insertBatch(@RequestBody List<T> ts) {
        setDao();
        baseDao.insertBatch(ts);
        return null;
    }


    /**
     * 更新
     */
    @Transactional
    public Object updateByPrimaryKeySelective(@RequestBody T t) {
        setDao();
        return baseDao.updateByPrimaryKeySelective(t);
    }

    // 根据条件更新
    @Transactional
    public Object updateByExampleSelective(T t, Q q) {
        setDao();
        return baseDao.updateByExampleSelective(t, q);
    }

    @Transactional
    public Object updateByExample(T t, Q q) {
        setDao();
        return baseDao.updateByExample(t, q);
    }

    @Transactional
    public Object updateByPrimaryKey(T t) {
        setDao();
        return baseDao.updateByPrimaryKey(t);
    }

    @Transactional(readOnly = true)
    public int countByExample(@RequestBody Q example) {
        setDao();
        return baseDao.countByExample(example);

    }

    /**
     * 删除
     */
    @Transactional
    public int deleteByPrimaryKey(@PathVariable("id") P id) {
        setDao();
        return baseDao.deleteByPrimaryKey(id);
    }

    /**
     * 删除
     */
    @Transactional
    public int deleteByPrimaryKeys(@PathVariable("ids") List<P> ids) {
        setDao();
        return baseDao.deleteByPrimaryKeys(ids);
    }

    @Transactional
    public int deleteByExample(@RequestBody Q q) {
        setDao();
        return baseDao.deleteByExample(q);
    }


    public P getPrimaryKey() {
        return null;
    }

    public void setPrimaryKey(T t) {
    }
}
